package me.numark.fragments;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;

import org.json.JSONObject;

import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import me.numark.R;
import me.numark.net.AuthorizedJsonObjectRequest;
import me.numark.net.NetworkConstants;
import me.numark.net.NetworkHelper;
import me.numark.net.UploadImageRequest;
import me.numark.utils.FileUtils;
import me.numark.utils.ImageUtils;
import me.numark.utils.LogUtils;
import me.numark.utils.Settings;
import me.numark.view.CircleImageView;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * to handle interaction events.
 * Use the {@link PersonalInfoFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class PersonalInfoFragment extends Fragment implements View.OnClickListener {

    private RegisterListener mListener;

    private EditText nickEdit;

    private EditText introEdit;

    private TextView chooseAvatar;

    private CircleImageView avatar;

    private TextView rightButton;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment PersonalInfoFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static PersonalInfoFragment newInstance() {
        PersonalInfoFragment fragment = new PersonalInfoFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public PersonalInfoFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_personal_info, container, false);
        TextView title = (TextView) view.findViewById(R.id.title);
        title.setText(R.string.finish_intro);
        view.findViewById(R.id.back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().finish();
            }
        });
        nickEdit = (EditText) view.findViewById(R.id.nick_edit);
        if (!TextUtils.isEmpty(Settings.getNick())) {
            nickEdit.setText(Settings.getNick());
        }
        introEdit = (EditText) view.findViewById(R.id.intro_edit);
        chooseAvatar = (TextView) view.findViewById(R.id.choose_avatar);
        chooseAvatar.setOnClickListener(this);
        avatar = (CircleImageView) view.findViewById(R.id.avatar);
        avatar.setOnClickListener(this);
        BitmapDrawable drawable = FileUtils.getAvatarDrawable();
        if (drawable != null) {
            avatarImage = drawable.getBitmap();
            hasUpdatedAvatar = false;
            avatar.setImageDrawable(drawable);
        }
        rightButton = (TextView) view.findViewById(R.id.right_text);
        rightButton.setOnClickListener(this);
        rightButton.setText(R.string.next_step);
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (RegisterListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.choose_avatar:
            case R.id.avatar:
                ImageUtils.takeOrChoosePhoto(this, ImageUtils.TAKE_OR_CHOOSE_PHOTO);
                break;
            case R.id.right_text:
                String nick = nickEdit.getText().toString();
                if (TextUtils.isEmpty(nick) || nick.length() < 3) {
                    Toast.makeText(getActivity(), R.string.nick_too_short, Toast.LENGTH_SHORT)
                            .show();
                    return;
                } else if (TextUtils.isEmpty(introEdit.getText().toString())) {
                    Toast.makeText(getActivity(), R.string.no_intro, Toast.LENGTH_SHORT).show();
                    return;
                } else if(!hasUpdatedAvatar) {
                    Toast.makeText(getActivity(), R.string.no_avatar, Toast.LENGTH_SHORT).show();
                    return;
                }
                setPersonalInfo(avatarImage);
                break;
        }
    }

    private boolean hasUpdatedAvatar = false;

    private Bitmap avatarImage = null;

    private static final String TAG = PersonalInfoFragment.class.getCanonicalName();

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        LogUtils.d(TAG, "onActivityResult, requestCode is " + requestCode + ", data is " + data);
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        switch (requestCode) {
            case ImageUtils.TAKE_OR_CHOOSE_PHOTO:
                File f = ImageUtils.getPhotoFromResult(getActivity(), data);
                ImageUtils.doCropPhoto(this, f);
                break;
            case ImageUtils.PHOTO_PICKED_WITH_DATA:
                avatarImage = ImageUtils.getCroppedImage();
                avatar.setImageBitmap(avatarImage);
                avatar.setVisibility(View.VISIBLE);
                hasUpdatedAvatar = true;
                break;
        }
    }

    private void setPersonalInfo(final Bitmap avatarImage) {
        String uid = Settings.getUid();
        String url = String.format(NetworkConstants.UPDATE_AVATAR_URL, uid);
        UploadImageRequest request = new UploadImageRequest(getActivity(), url, "user_pic",
                avatarImage, new UploadImageRequest.ResultListener() {
            @Override
            public void onSuccess(String msg) {
                mListener.onSuccess(null);
                ImageUtils.saveAvatar(avatarImage, getActivity());
                try {
                    uploadProfile();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(String msg) {
                mListener.onFailure(msg);
            }
        });
        request.execute();
        mListener.onShowProgress(getString(R.string.uploading));
    }

    private void uploadProfile() throws UnsupportedEncodingException {
        String uid = Settings.getUid();
        String url = String.format(NetworkConstants.PROFILE_URL, uid) + "?des=" + URLEncoder
                .encode(introEdit.getText().toString(), "utf-8") + "&nick=" + URLEncoder
                .encode(nickEdit.getText().toString(), "utf-8");
        AuthorizedJsonObjectRequest request = new AuthorizedJsonObjectRequest(Request.Method.POST,
                url,
                null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        LogUtils.d("response is " + response);
                        if (response.optBoolean("ret")) {
                            mListener.onNext(PersonalInfoFragment.this, null);
                            Settings.saveNick(nickEdit.getText().toString());
                            Settings.saveDescription(introEdit.getText().toString());
                        } else {
                            mListener.onFailure(response.optString("msg",
                                    getString(R.string.set_profile_failed)));
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                mListener.onFailure(getString(R.string.set_profile_failed));
            }
        });
        NetworkHelper.getInstance().getRequestQueue().add(request);
        NetworkHelper.getInstance().getRequestQueue().start();
    }

}
